﻿#include"List.h"
#include"String.h"

//int main()
//{
//	yyc::List<yyc::string> lt;
//
//	yyc::string s1("111111111111111111111");
//	lt.push_back(s1);
//	cout << "*************************" << endl;
//
//	lt.push_back(yyc::string("22222222222222222222222222222"));
//	cout << "*************************" << endl;
//
//	lt.push_back("3333333333333333333333333333");
//	cout << "*************************" << endl;
//
//	lt.push_back(move(s1));
//	cout << "*************************" << endl;
//
//	return 0;
//}

//int main()
//{
//	yyc::List<yyc::string> lt;
//	cout << "*********************************" << endl;
//
//	// 传左值，跟push_back一样，走拷贝构造
//	yyc::string s1("111111111111");
//	lt.emplace_back(s1);
//	//lt.push_back(s1);
//	cout << "*********************************" << endl;
//
//	// 右值，跟push_back一样，走移动构造
//	lt.emplace_back(move(s1));
//	//lt.push_back(move(s1));
//	cout << "*********************************" << endl;
//
//	// 直接把构造string参数包往下传，直接用string参数包构造string
//	// 这里达到的效果是push_back做不到的
//	lt.emplace_back("111111111111");
//	lt.push_back("111111111111");
//	cout << "*********************************" << endl;
//
//
//	//yyc::List<pair<yyc::string, int>> lt1;
//	//cout << "*********************************" << endl;
//
//	//// 跟push_back一样
//	//// 构造pair + 拷贝/移动构造pair到list的节点中data上
//	//pair<yyc::string, int> kv("苹果", 1);
//	//lt1.emplace_back(kv);
//	//lt1.push_back(kv);
//	//cout << "*********************************" << endl;
//
//	//// 跟push_back一样
//	//lt1.emplace_back(move(kv));
//	////lt1.push_back(move(kv));
//	//cout << "*********************************" << endl;
//
//	////lt1.emplace_back({ "苹果", 1 }); // 不能
//	//lt1.emplace_back("苹果", 1 );
//	//lt1.push_back({ "苹果", 1 });
//	//cout << "*********************************" << endl;
//
//	return 0;
//}

//引用折叠
//typedef int& lref;
//typedef int&& rref;
//
//// 由于引用折叠限定，f1实例化以后总是一个左值引用
//template<class T>
//void f1(T& x)
//{}
//
//// 由于引用折叠限定，f2实例化后可以是左值引用，也可以是右值引用
//// 万能引用
//template<class T>
//void f2(T&& x)
//{}
//
//int main()
//{
//	int n = 0;
//	lref& r1 = n; // r1 的类型是 int&
//	lref&& r2 = n; // r2 的类型是 int&
//	rref& r3 = n; // r3 的类型是 int&
//	rref&& r4 = 1; // r4 的类型是 int&&
//	
//	// 没有折叠->实例化为void f1(int& x)
//	f1<int>(n);
//	//f1<int>(0); // 报错
//	
//	// 折叠->实例化为void f1(int& x)
//	f1<int&>(n);
//	//f1<int&>(0); // 报错
//	
//	// 折叠->实例化为void f1(int& x)
//	f1<int&&>(n);
//	//f1<int&&>(0); // 报错
//	
//	// 折叠->实例化为void f1(const int& x)
//	f1<const int&>(n);
//	f1<const int&>(0);
//	
//	// 折叠->实例化为void f1(const int& x)
//	f1<const int&&>(n);
//	f1<const int&&>(0);
//	
//	// 没有折叠->实例化为void f2(int&& x)
//	//f2<int>(n); // 报错
//	f2<int>(0);
//	
//	// 折叠->实例化为void f2(int& x)
//	f2<int&>(n);
//	//f2<int&>(0); // 报错
//	
//	// 折叠->实例化为void f2(int&& x)
//	//f2<int&&>(n); // 报错
//	f2<int&&>(0);
//
//	return 0;
//}

// 万能引用
//template<class T>
//void Function(T&& t)
//{
//	int a = 0;
//	T x = a;
//	//x++;
//
//	cout << &a << endl;
//	cout << &x << endl << endl;
//}
//
//int main()
//{
//	// 10是右值，推导出T为int，模板实例化为void Function(int&& t)，不折叠
//	Function(10);
//
//	int a;
//	// a是左值，推导出T为int&，引用折叠，模板实例化为void Function(int& t)
//	Function(a);
//
//	// std::move(a)是右值，推导出T为int，模板实例化为void Function(int&& t)，不折叠
//	Function(std::move(a)); // 右值
//
//	const int b = 8;
//	// b是左值，推导出T为const int&，引用折叠，模板实例化为void Function(const int&t)
//	// 所以Function内部会编译报错，x不能++
//	Function(b); // const 左值
//
//	// std::move(b)右值，推导出T为const int，模板实例化为void Function(const int&&t)
//	// 所以Function内部会编译报错，x不能++
//	Function(std::move(b)); // const 右值
//
//	return 0;
//}

///////////////////////////////////////////////////////////////////////////////////////////////
//void Fun(int& x) { cout << "左值引用" << endl; }
//void Fun(const int& x) { cout << "const 左值引用" << endl; }
//void Fun(int&& x) { cout << "右值引用" << endl; }
//void Fun(const int&& x) { cout << "const 右值引用" << endl; }
//
//// 万能引用
//template<class T>
//void Function(T&& t)
//{
//	// 保持t的属性
//	Fun(forward<T>(t));//完美转发：forward
//}
//
//int main()
//{
//	// 10是右值，推导出T为int，模板实例化为void Function(int&& t)
//	Function(10); // 右值
//
//	int a;
//	// a是左值，推导出T为int&，引用折叠，模板实例化为void Function(int& t)
//	Function(a); // 左值
//
//	// std::move(a)是右值，推导出T为int，模板实例化为void Function(int&& t)
//	Function(std::move(a)); // 右值
//
//	const int b = 8;
//	// a是左值，推导出T为const int&，引用折叠，模板实例化为void Function(const int& t)
//	Function(b);
//
//	// std::move(b)右值，推导出T为const int，模板实例化为void Function(const int&& t)
//	Function(std::move(b)); // const 右值
//
//	return 0;
//}

//emplace系列和push系列

//int main()
//{
//	//yyc::List<yyc::string> lt;
//	//cout << "*********************************" << endl;
//
//	//// 传左值，跟push_back一样，走拷贝构造
//	//yyc::string s1("111111111111");
//	////lt.emplace_back(s1);
//	//lt.push_back(s1);
//	//cout << "*********************************" << endl;
//
//	//// 右值，跟push_back一样，走移动构造
//	//lt.emplace_back(move(s1));
//	////lt.push_back(move(s1));
//	//cout << "*********************************" << endl;
//
//	//// 直接把构造string参数包往下传，直接用string参数包构造string
//	//// 这里达到的效果是push_back做不到的
//	//lt.emplace_back("111111111111");
//	//lt.push_back("111111111111");
//	//cout << "*********************************" << endl;
//
//
//	yyc::List<pair<yyc::string, int>> lt1;
//	cout << "*********************************" << endl;
//
//	// 跟push_back一样
//	// 构造pair + 拷贝/移动构造pair到list的节点中data上
//	pair<yyc::string, int> kv("苹果", 1);
//	lt1.emplace_back(kv);
//	lt1.push_back(kv);
//	cout << "*********************************" << endl;
//
//	// 跟push_back一样
//	lt1.emplace_back(move(kv));
//	//lt1.push_back(move(kv));
//	cout << "*********************************" << endl;
//
//	//lt1.emplace_back({ "苹果", 1 }); // 不能:加上{}后就类型不明确
//	lt1.emplace_back("苹果", 1 );
//	lt1.push_back({ "苹果", 1 });//多参数的隐式类型转换
//	cout << "*********************************" << endl;
//
//	return 0;
//}

class Person
{
public:
	Person(const char* name = "xxxxxx", int age = 18)
		:_name(name)
		, _age(age)
	{}
	/*~Person()
	{}*/

private:
	yyc::string _name;
	int _age;
};
//如果你没有自己实现移动构造函数，且没有实现析构函数 、拷贝构造、拷贝赋值重载中的任意⼀
//个。那么编译器会自动⽣成⼀个默认移动构造。默认生成的移动构造函数，对于内置类型成员会执
//⾏逐成员按字节拷贝，自定义类型成员，则需要看这个成员是否实现移动构造，如果实现了就调用
//移动构造，没有实现就调用拷贝构造。

//如果你没有自己实现移动赋值重载函数，且没有实现析构函数 、拷贝构造、拷贝赋值重载中的任意
//一个，那么编译器会自动⽣成⼀个默认移动赋值
//默认移动赋值跟上面移动构造完全类似

int main()
{
	Person s1;
	Person s2 = s1;
	Person s3 = std::move(s1);

	Person s4;
	s4 = std::move(s2);

	return 0;
}